package fr.umlv.proxir.page;

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;


/*
 * RAM implementation of a page
 * the content in in java virtual machine memory
 */
public class PageInRAM implements Page{
	private final List<byte[]> content = new LinkedList<byte[]>();
	private final HashMap<String, String> headers = new HashMap<String, String>();
	private int pageCounter;

	/**
	 * creates an empty page with a number of visit of 0
	 */
	public PageInRAM() {
		this.pageCounter = 0;
	}

	/**
	 * creates a page with the requested content
	 * @param content page content
	 */
	public PageInRAM(byte[] content) {
		addBuffer(content);
		this.pageCounter = 0;
	}


	/**
	 * returns the size in bytes of the page
	 * 
	 * @return page size
	 */
	public int getSize(){
		return content.size();
	}

	/**
	 * adds a byte[] to the current page
	 * 
	 * @param buff
	 *            buffer to add
	 */
	public void addBuffer(byte[] buff){
		//System.out.println(new String(buff));
		content.add(buff);
	}

	/**
	 * returns the page content
	 * 
	 * @return page content
	 */
	public List<byte[]> getContent(){
		//The number the page is requested
		this.pageCounter++;

		return content;
	}

	/**
	 * returns the number of times the page have been requested
	 * 
	 * @return page counter
	 */
	public int getPageCounter(){
		return pageCounter;
	}

	/**
	 * sets the number of times the page have been requested
	 * 
	 * @param pageCounter
	 *            the number of visits
	 */
	public void setPageCounter(int pageCounter){
		this.pageCounter=pageCounter;
	}

	/**
	 * the String representation of a page
	 * @return String representation
	 */
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		for(byte[] buff : content){
			sb.append(new String (buff));
		}

		return sb.toString();
	}

	/**
	 * return the value of the Content-type header
	 * @return content type of the page
	 */
	public String getContentType(){
		if(headers.containsKey("Content-Type:"))return headers.get("Content-Type:");
		return parseHeaders("Content-Type:");
	}

	/**
	 * parses header in first content byte and return header value
	 * @param header string representation the requested header
	 * @return the value of the requested header
	 */
	private String parseHeaders(String header){
		String httpHeader = new String(content.get(0));
		if(!httpHeader.contains(header))return null;

		Scanner sc = new Scanner(httpHeader);
		while (sc.hasNextLine()) {
			String line = sc.nextLine();
			if (line.contains(header)) {
				sc = new Scanner(line);
				String split[] = line.split(" ");
				if(split[1].endsWith(";"))split[1] = split[1].split(";")[0];
				headers.put(split[0], split[1]);
				return split[1];
			}

		}
		return null;
	}

	/**
	 * return the value of the Content-encoding header
	 * @return content encoding of the page
	 */
	public String getContentEncoding(){
		if(headers.containsKey("Content-Encoding:"))return headers.get("Content-Encoding:");
		return parseHeaders("Content-Encoding:");
	}

	/**
	 * return the value of the Date header
	 * @return date value of the page
	 */
	public String getDate(){
		if(headers.containsKey("Date:"))return headers.get("Date:");
		return parseHeaders("Date:");
	}

	/**
	 * return the value of the Content-Length header
	 * @return content length of the page
	 */
	public String getContentLength(){
		if(headers.containsKey("Content-Length:"))return headers.get("Content-Length:");
		return parseHeaders("Content-Length:");
	}

	/**
	 * return the value of the Content-Language header
	 * @return content language of the page
	 */
	public String getContentLanguage(){
		if(headers.containsKey("Content-Language:"))return headers.get("Content-Language:");
		return parseHeaders("Content-Language:");
	}

	/**
	 * return the value of the Location header
	 * @return Location of the page
	 */
	public String getLocation(){
		if(headers.containsKey("Location:"))return headers.get("Location:");
		return parseHeaders("Location:");
	}

	/**
	 * return the value of the Forwarded header
	 * @return Forwarded value of the page
	 */
	public String getForwarded(){
		if(headers.containsKey("Forwarded:"))return headers.get("Forwarded:");
		return parseHeaders("Forwarded:");
	}

	/**
	 * return the value of the Expires header
	 * @return Expiration time of the page
	 */
	public String getExpires(){
		if(headers.containsKey("Expires:"))return headers.get("Expires:");
		return parseHeaders("Expires:");
	}

	/**
	 * return the value of the Server header
	 * @return Server of the page
	 */
	public String getServer(){
		if(headers.containsKey("Server:"))return headers.get("Server:");
		return parseHeaders("Server:");
	}

	/**
	 * return the value of the Charset header
	 * @return Charset of the page
	 */	
	public String getCharset(){
		if(headers.containsKey("charset="))return headers.get("charset=");

		String httpHeader = new String(content.get(0));
		if(!httpHeader.contains("charset="))return null;

		Scanner sc = new Scanner(httpHeader);
		while (sc.hasNextLine()) {
			String line = sc.nextLine();
			if (line.contains("charset=")) {
				sc = new Scanner(line);
				//System.out.println("La ligne est la suivante :"+line);
				String	split = line.split(" ")[2];
				String  charset = split.split("=")[1];
				if(Charset.availableCharsets().containsKey(charset)){
					headers.put("charset=", charset);
					return charset;
				}else{
					return null;
				}
			}

		}
		return null;
	}

}
